import greenfoot.Greenfoot;

/**
 * Esta clases ayuda a la creacion de vectores en el juego
 * 
 * @author Gabriel Duron 
 * @version 04/04/13
 */
public final class Vector  
{
    /**
     * variable de instancia posicion
     */
    double dx;
    /**
     * variable de instancia posicion
     */
    double dy;
    /**    
     * variable de instancia direccion
     */
    int direccion;
    /**
     * variable de instancia largo o ancho
     */
    double largo;

    /**
     * constructor de la clase vector
     */
    public Vector()
    {
    }
    
    /**
     * Retorna un vector al azar con limites de longitud definidos
     */
    public static Vector random(int longMax)
    {
        return new Vector (Greenfoot.getRandomNumber(360), Greenfoot.getRandomNumber(longMax));
    }
    
    /**
     * Crean un vector con la longitud y direccion dadas, la direccion debe
     * estar en el rango [0...359], donde 0 es este , y los grados incrementan
     * hacia la direccion de las manecillas del reloj.
     */
     public Vector(int direccion, double largo)
    {
        this.largo = largo;
        this.direccion = direccion;
        actualizaLoc();
    }
    
    /**
     * Crea un vector con la posicion de inicio y fin y actualiza su direccion
     */    
     public Vector(Lugar inicio, Lugar fin)
    {
        dx = fin.getX() - inicio.getX();
        dy = fin.getY() - inicio.getY();
        actualizaDir();
    }
    
    /**
     * asigna la direccion del vector.
     */
    public void asignaDireccion(int direccion) {
        this.direccion = direccion;
        actualizaLoc();
    }
    
    /**
     * Agrega otro vector a este vector. 
     */
    public void agrega(Vector otro) {
        dx += otro.dx;
        dy += otro.dy;
        actualizaDir();
    }
    
    /**
     * reduce el ancho del vector
     */
    public void reduceAncho(double d) {
        largo = largo - d;
        actualizaLoc();
    }
    
    /**
     * hace que el vector encoga
     */
    public void escala(double factor) {
      largo = largo * factor;
      actualizaLoc();
    }
    
    /**
     * crea un vector neutral
     */
    void setNeutral() {
        dx = 0.0;
        dy = 0.0;
        largo = 0.0;
        direccion = 0;
    }
    
    /**
     * actualiza la direccion y el ancho del actual dx, dy
     */
    private void actualizaDir() {
        this.direccion = (int) Math.toDegrees(Math.atan2(dy, dx));
        this.largo = Math.sqrt(dx*dx+dy*dy);
    }
    
    /**
     * actualiza dx y dy del actual direccion y ancho
     */
    private void actualizaLoc() {
        dx = largo * Math.cos(Math.toRadians(direccion));
        dy = largo * Math.sin(Math.toRadians(direccion));
    }
    
    /**
     * regrsa la posicion en X
     */
     public double getX() {
        return dx;
    }
    
     /**
     * regresa la posicion en Y
     */
    public double getY() {
        return  dy;
    }
    
    /**
     * regresa la direccion del vector
     */
    public int getDirection() {
        return direccion;
    }
    
    /**
     * regresa el largo del vector
     */
    public double getLength() {
        return largo;
    }
    
    /**
     * Crea una copia de este vector
     */
    public Vector reverse() { 
        Vector copia = new Vector();
        copia.dx = -dx;
        copia.dy = -dy;
        copia.direccion = (direccion + 180) % 360;
        copia.largo = largo;
        return copia;
    }
    
    /**
     * regresa las coordenada del vector en forma de cadena.
     */
     public String toString() {
        return "[" + direccion + " " + largo + " / " + dx + "," + dy + "]";
    }
        
}
